

package org.tools;


public class RuleUtil
{

	public static int rate = 0xf4240;

	public RuleUtil()
	{
	}

	public static int toInt(String coordinate)
	{
		double dx = Double.parseDouble(coordinate);
		Double rdx = new Double(dx * (double)rate);
		long lx = rdx.longValue();
		int ix = (int)lx;
		return ix;
	}

	public static int m2Int(String m)
	{
		return Integer.parseInt(m) * rate;
	}

	public static double getDistance(double jd1, double wd1, double jd2, double wd2)
	{
		double PI = 3.1415926535898002D;
		double R = 6371229D;
		double x = ((jd2 - jd1) * PI * R * Math.cos((((wd1 + wd2) / 2D) * PI) / 180D)) / 180D;
		double y = ((wd2 - wd1) * PI * R) / 180D;
		double out = Math.hypot(x, y);
		return out;
	}

	public static double distanceByLnglat(double _Longitude1, double _Latidute1, double _Longitude2, double _Latidute2)
	{
		double radLat1 = (_Latidute1 * 3.1415926535897931D) / 180D;
		double radLat2 = (_Latidute2 * 3.1415926535897931D) / 180D;
		double a = radLat1 - radLat2;
		double b = (_Longitude1 * 3.1415926535897931D) / 180D - (_Longitude2 * 3.1415926535897931D) / 180D;
		double s = 2D * Math.asin(Math.sqrt(Math.pow(Math.sin(a / 2D), 2D) + Math.cos(radLat1) * Math.cos(radLat2) * Math.pow(Math.sin(b / 2D), 2D)));
		s *= 6378137D;
		s = Math.round(s * 10000D) / 10000L;
		return s;
	}

	public static double computeLength(String dwStartX, String dwStartY, String dwEndX, String dwEndY)
	{
		return computeLength(Double.parseDouble(dwStartX), Double.parseDouble(dwStartY), Double.parseDouble(dwEndX), Double.parseDouble(dwEndY));
	}

	public static double computeLength(double dwStartX, double dwStartY, double dwEndX, double dwEndY)
	{
		double PI = 3.1415926535898002D;
		double latRadians1 = dwStartY * (PI / 180D);
		double latRadians2 = dwEndY * (PI / 180D);
		double latRadians = latRadians1 - latRadians2;
		double lngRadians = dwStartX * (PI / 180D) - dwEndX * (PI / 180D);
		double f = 2D * Math.asin(Math.sqrt(Math.pow(Math.sin(latRadians / 2D), 2D) + Math.cos(latRadians1) * Math.cos(latRadians2) * Math.pow(Math.sin(lngRadians / 2D), 2D)));
		return f * 6378137D;
	}

	public static double[] getDroopPt(double startDX, double startDY, double endDX, double endDY, 
			double coordDX, double coordDY)
	{
		double droop[] = new double[2];
		double NEARZERO = 9.9999999999999998E-017D;
		if ((startDX - endDX) * (startDX - endDX) + (startDY - endDY) * (startDY - endDY) < NEARZERO)
		{
			droop[0] = startDX;
			droop[1] = startDY;
			return droop;
		}
		if ((startDX - endDX) * (startDX - endDX) < NEARZERO)
		{
			droop[0] = startDX;
			droop[1] = coordDY;
			if ((droop[1] - startDY) * (droop[1] - startDY) < NEARZERO)
				return droop;
			if ((droop[1] - endDY) * (droop[1] - endDY) < NEARZERO)
				return droop;
			if (startDY < endDY)
			{
				if (droop[1] < startDY)
					return droop;
				if (droop[1] < endDY)
					return droop;
				else
					return droop;
			}
			if (droop[1] > startDY)
				return droop;
			if (droop[1] > endDY)
				return droop;
			else
				return droop;
		}
		if ((startDY - endDY) * (startDY - endDY) < NEARZERO)
		{
			droop[0] = coordDX;
			droop[1] = startDY;
		} else
		{
			double dK = (startDY - endDY) / (startDX - endDX);
			droop[0] = (dK * (coordDY - startDY) + dK * dK * startDX + coordDX) / (dK * dK + 1.0D);
			droop[1] = dK * (droop[0] - startDX) + startDY;
		}
		if ((droop[0] - startDX) * (droop[0] - startDX) < NEARZERO)
			return droop;
		if ((droop[0] - endDX) * (droop[0] - endDX) < NEARZERO)
			return droop;
		if (startDX < endDX)
		{
			if (droop[0] < startDX)
				return droop;
			if (droop[0] < endDX)
				return droop;
			else
				return droop;
		}
		if (droop[0] > startDX)
			return droop;
		if (droop[0] > endDX)
			return droop;
		else
			return droop;
	}

	public static double minDistenceOfPoint2Line(double x1, double y1, double x2, double y2, 
			double x0, double y0)
	{
		double space = 0.0D;
		double a = computeLength(x1, y1, x2, y2);
		double b = computeLength(x1, y1, x0, y0);
		double c = computeLength(x2, y2, x0, y0);
		if (c <= 9.9999999999999995E-007D || b <= 9.9999999999999995E-007D)
		{
			space = 0.0D;
			return space;
		}
		if (a <= 9.9999999999999995E-007D)
		{
			space = b;
			return space;
		}
		if (c * c >= a * a + b * b)
		{
			space = b;
			return space;
		}
		if (b * b >= a * a + c * c)
		{
			space = c;
			return space;
		} else
		{
			double p = (a + b + c) / 2D;
			double s = Math.sqrt(p * (p - a) * (p - b) * (p - c));
			space = (2D * s) / a;
			return space;
		}
	}

	public static void main(String args[])
	{
		System.out.println(getDistance(118.126592D, 30.130026000000001D, 118.12669200000001D, 30.130026000000001D));
		System.out.println(computeLength(118.126592D, 30.130026000000001D, 118.12669200000001D, 30.130026000000001D));
		System.out.println(distanceByLnglat(118.126592D, 30.130026000000001D, 118.12669200000001D, 30.130026000000001D));
		
		double n[] = getDroopPt(118.126592D, 30.130026000000001D, 118.12669200000001D, 30.130126000000001D, 118.12660200000001D, 30.130255999999999D);
		System.out.println(n[0]);
		System.out.println(n[1]);
	
	}

}
